
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<ctype.h>
#include<netdb.h>
#include<time.h>
#include<fcntl.h>
#include<dirent.h>
#include<getopt.h>
#include<libgen.h>
#include<fcntl.h>
#include<unistd.h>
#include<pthread.h>
#include<signal.h>
#include<sqlite3.h>

#include"cJSON.h"
#include"client_temperature.h"
#include"mosquitto.h"
#include"client_time.h"
#include"client_sqlite.h"
#include"platform.h"
#include"logger.h"
#include"client_pthread.h"
#define MSG_MAX_SIZE 1024//缓冲区最大容量

void print_usage(char *progname);
void signal_stop(int signum);//信号
bool session=true;
int  sig_stop;
int  connect_flag;

typedef void *(thread_worker) (void *args);
extern int thread_init(pthread_t *tid,thread_worker* thread_work,void * args);
void *thread_work(void * args);
//void *mqtt_work_sub(void *ctx_sub);
//void *mqtt_work_pub(void *ctx_pub);

/*选项说明*/
void   print_usage(char *progname){
        printf("-d(--daemon)running background\n");
        printf("-h(--help):\n");
        printf("-A(--aliyun):\n");
        printf("-H(--huaweiyun)\n");
        printf("-T(--tencent)\n");
        return;
}


int main(int argc,char* argv[])
{
        int                     rv=-1;
        sqlite3                 *db;
        struct  mosquitto       *mosq=NULL;
        //char                  *get_ip;
        struct hostent          *get_host;
        char                    buf[MSG_MAX_SIZE];
        char                    send_json[MSG_MAX_SIZE];
        char                    unsend_json[MSG_MAX_SIZE];
        int                     opt;
        int                     daemon_run=0;
        float                   temperature;
        char                    T_time[64];
        int                     log_fd;
        msq_ctx_t               msq;
        pthread_t               tid;
        time_t                  current_time=0;
        time_t                  last_time=0;
        int                     need_seconds=5;
        char                    *str1="ali";
        char                    *str2="huawei";
        char                    *str3="tencent";
        int                     check_flag;
        int                     con_flag=-1;
        void                    *args;




        struct option   opts[]={
                {"daemon",no_argument,NULL,'d'},
                {"help", no_argument, NULL, 'h'},
                {"aliyun",no_argument,NULL,'A'},
                {"huaweiyun",no_argument,NULL,'H'},
                {"tencentyun",no_argument,NULL,'T'},
                {NULL,0,NULL,0},
        };
        while((opt=getopt_long(argc,argv,"dhAHT",opts,NULL))!=-1)
        {
                switch(opt)
                {

                        case'd':
                                daemon_run=1;
                                break;
                        case 'h':
                                print_usage(argv[0]);
                                return 0;
                        case 'A':
                                printf("a\n");
                                strncpy(msq.p_ctx.platform,str1,sizeof(msq.p_ctx.platform));
                                printf("platform=%s\n",msq.p_ctx.platform);

                                break;
                        case 'H':
                                printf("huawei\n");
                                strncpy(msq.p_ctx.platform,str2,strlen(str2));
                                printf("platform=%s\n",msq.p_ctx.platform);

                                break;
                        case 'T':
                                printf("tencent\n");
                                strncpy(msq.p_ctx.platform,str3,strlen(str3));
                                break;
                        default:
                                break;

                }
        }

        /*解析配置文件*/
        get_config(&msq);
#if 1
        printf("platform=%s\n",msq.p_ctx.platform);
        printf("clientid=%s\n",msq.p_ctx.clientid);
        printf("hostname=%s\n",msq.p_ctx.hostname);
        printf("username=%s\n",msq.p_ctx.username);
        printf("password=%s\n",msq.p_ctx.password);
        printf("id=%s\n",msq.p_ctx.id);
        printf("sub_topic=%s\n",msq.sub_ctx.sub_topic);
        printf("pub_topic=%s\n",msq.pub_ctx.pub_topic);
        printf("port=%d\n",msq.p_ctx.port);
        printf("keepalive=%d\n",msq.p_ctx.keepalive);
        printf("mosq=%s\n",msq.p_ctx.mosq);
#endif

#if 1
        /*域名解析*/
        if(msq.p_ctx.hostname){
                printf("hostname=%s\n",msq.p_ctx.hostname);
                get_host = gethostbyname(msq.p_ctx.hostname);
                if(!get_host)
                {
                        printf("gethostbyname() get ip failure:%s\n", strerror(errno));
                        rv = -1;
                }

                msq.p_ctx.get_ip = inet_ntoa(*(struct in_addr *)get_host->h_addr);
                printf("DNS ip is:%s\n", msq.p_ctx.get_ip);
        }
        if(!msq.p_ctx.port&&(!msq.p_ctx.hostname||!msq.p_ctx.get_ip)&&(!msq.p_ctx.platform)){
                print_usage(argv[0]);
                return 0;
        }
#endif
        /*设置守护进程*/
        if(daemon_run){
                if ((daemon(1, 1)) < 0){
                        log_error("This is error level message!");
                        return 0;
                }
                printf("Program %s is running at the background now\n",argv[0]);
        }


        /*日志*/
        if( logger_init("temperature.log", LOG_LEVEL_DEBUG) < 0){
                fprintf(stderr, "initial logger system failure\n");
                return -1;
        }

        rv=mosquitto_lib_init();
        if(rv!=MOSQ_ERR_SUCCESS){
                printf("mosquitto init failure:%s\n",strerror(errno));
                return -2;
        }
        else{
                printf("mosquitto init successful\n");
        }

        mosq=mosquitto_new(msq.p_ctx.clientid,session,NULL);

        if(!mosq){
                printf("new pub_test failure:%s\n",strerror(errno));
                return -3;
        }
        else{
                printf("create mosquitto successful\n");
        }
        msq.p_ctx.mosq=mosq;

        rv=mosquitto_username_pw_set(msq.p_ctx.mosq,msq.p_ctx.username,msq.p_ctx.password);//在connect之前调用这个函数
        if(rv!=MOSQ_ERR_SUCCESS){
                printf("set username and password failure:%s\n",strerror(errno));
                return -4;
        }
        sqlite_open_create(db);

        con_flag=mosquitto_connect(msq.p_ctx.mosq,msq.p_ctx.get_ip,msq.p_ctx.port,msq.p_ctx.keepalive);
        if(con_flag!=MOSQ_ERR_SUCCESS){
                printf("mosquitto_connect failure:%s\n",strerror(errno));
                return -1;
        }
        else{
                printf("mosquitto_connect successfully\n");
                rv=mosquitto_subscribe(msq.p_ctx.mosq,NULL,msq.sub_ctx.sub_topic,msq.sub_ctx.sub_qos);
                if(rv!=MOSQ_ERR_SUCCESS){
                        printf("mosquitto sub failure:%s\n",strerror(errno));
                }
                else{
                        printf("mosquitto sub success\n");
                }
                rv=mosquitto_loop_start(mosq);
                if(rv!=MOSQ_ERR_SUCCESS){
                        printf("mosquitto_loop failure:%s\n",strerror(errno));
                        return -1;
                }
                printf("loop ok!\n");
                sleep(1);
        }

        //signal(SIGTERM,signal_stop);
        thread_init(&tid,thread_work,&msq);
        signal(SIGTERM,signal_stop);

        while(!sig_stop){
                /*控制采样时间*/
                current_time = time(NULL);
                if((current_time - last_time) >= need_seconds)
                {   /*获取采样温度*/
                        check_flag=1;
                        get_temperature(&temperature);
                        if(temperature<0){
                                printf("read temperature failure:%s\n",strerror(errno));
                                check_flag=0;
                                continue;
                        }
                        printf("read temperature successful\n");
                        get_time(T_time);
                        if(T_time<0){
                                printf("get time failure:%s\n",strerror(errno));
                                check_flag=0;
                                continue;
                        }
                        if(check_flag==1){
                                memset(&msq.info_ctx,0,sizeof(msq.info_ctx));
                                strcpy(msq.info_ctx.name,"0001");
                                strncpy(msq.info_ctx.T_time,T_time,strlen(T_time));
                                msq.info_ctx.temperature=temperature;
                                pack_data(&msq,buf,sizeof(buf));
                                //con_flag= mosquitto_connect(mosq,get_ip,msq.p_ctx.port,msq.p_ctx.keepalive);
                                printf("connect_flag=%d\n",connect_flag);
                                if(connect_flag!=1){
                                        printf("The connection was lost after obtaining data\n ");
                                        sqlite_insert(db,buf);
                                        continue;
                                }
                                else{
                                        memset(send_json,0,sizeof(send_json));
                                        get_json(&msq,send_json);
                                        printf("send_json=%s\n",send_json);
                                        rv=mosquitto_publish(msq.p_ctx.mosq,NULL,msq.pub_ctx.pub_topic,strlen(send_json)+1,send_json,msq.pub_ctx.pub_qos,0);
                                        if(rv!=MOSQ_ERR_SUCCESS){
                                                printf("mosquitto_publish failure:%s\n",strerror(errno));
                                                return -1;
                                                sqlite_insert(db,buf);
                                        }
                                        else{
                                                printf("publish successful\n");
                                                if( sqlite_get(db,&msq)>0){
                                                        memset(unsend_json,0,sizeof(unsend_json));
                                                        get_json(&msq,unsend_json);
                                                        rv=mosquitto_publish(msq.p_ctx.mosq, NULL,msq.pub_ctx.pub_topic, strlen(unsend_json)+1,unsend_json,msq.pub_ctx.pub_qos, NULL);
                                                        sleep(1);
                                                        if(rv!=MOSQ_ERR_SUCCESS){
                                                                printf("publish disconnect data failure:%s\n",strerror(errno));
                                                        }
                                                        else{
                                                                printf("publish data from sqlite\n");
                                                                sqlite_delete(db);
                                                        }
                                                 }
                                                else{
                                                        printf("sqlite have no data\n");
                                                        sleep(1);
                                                }

                                        }
                                }
                                        printf("time arrived and then into next loop\n");

                        }
                last_time = current_time;
                }

        }
        sqlite3_close(db);
        mosquitto_lib_cleanup();
        mosquitto_destroy(mosq);
        return 0;
}

void signal_stop(int signum)
{
        if(SIGTERM==signum)
        {
                printf("SIGTERM signal detected\n");
                sig_stop=1;
        }

}
